home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Pascal / Applications / Flight Stability / Flight Stability Source / CFSGameDirector.p < prev    next >
Encoding:
Text File  |  1995-07-15  |  9.3 KB  |  329 lines  |  [TEXT/PJMM]

  1. {****************************************************}
  2. {}
  3. {        CFSGameDirector.p                                                                                                                                                                                    }
  4. {}
  5. {        Director methods for the game window.                                                                                                                        }
  6. {}
  7. {        Copyright © 1995, Patrick Hew.  All rights reserved.                                                                            }
  8. {}
  9. {****************************************************}
  10.  
  11.  
  12. unit CFSGameDirector;
  13.  
  14. interface
  15.  
  16.     uses
  17.         TCL, FSIntf;
  18.  
  19. implementation
  20.  
  21.     const
  22.  
  23.         { Dimensions. }
  24.  
  25.         kEdgeMargin = 8;
  26.         kControlSpaceh = 20;
  27.  
  28.         kAircraftPanePosh = (kFSGameWindh - kAircraftPaneLenh) div 2;
  29.         kAircraftPanePosv = kEdgeMargin;
  30.  
  31.         kDirFieldPanePosh = kFSGameWindh div 2 - kDirFieldHalfWidth;
  32.         kDirFieldPanePosv = kAircraftPanePosv + kAircraftPaneLenv + kEdgeMargin;
  33.  
  34.         kAutopilotButtonLenh = 96;
  35.         kCheckBoxLenh = 80;
  36.         kStickPanePosh = kFSGameWindh div 2 - kStickHalfWidth;
  37.         kAutopilotButtonPosh = kStickPanePosh - kControlSpaceh - kAutopilotButtonLenh;
  38.         kAOACheckBoxPosh = kStickPanePosh + kStickHalfWidth * 2 + kControlSpaceh;
  39.         kBankCheckBoxPosh = kAOACheckBoxPosh;
  40.  
  41.         kAutopilotButtonLenv = 36; { Measured with ClarisWorks }
  42.         kCheckBoxesLenv = 16; { Measured with ClarisWorks }
  43.         kControlsPosv = kDirFieldPanePosv + kDirFieldHalfHeight * 2 + kEdgeMargin;
  44.         kAutopilotButtonPosv = kControlsPosv;
  45.         kStickPanePosv = kControlsPosv;
  46.         kBankCheckBoxPosv = kControlsPosv;
  47.         kAOACheckBoxPosv = kControlsPosv + kCheckBoxesLenv + kEdgeMargin;
  48.  
  49.         { String constants. These, and those used in BuildWindow, should be in a }
  50.         { resource so that the software can be localized. Of course, this is unlikely. }
  51.         { Note that we can't have string constants produced with Concat, so we }
  52.     { create them as variables and initialize them in IFSGameDirector. }
  53.  
  54.     const
  55.         kCarriageReturn = Chr(13);
  56.         kCommandKeySymbol = Chr(17);
  57.  
  58.     var
  59.         kTakeControlStr, kReleaseControlStr, kBankStr, kAOAStr: string;
  60.  
  61.  
  62. { IFSGameDirector }
  63. {}
  64. { Post: Our game director has been initialized. }
  65.  
  66.     procedure CFSGameDirector.IFSGameDirector;
  67.  
  68.     begin { IFSGameDirector }
  69.         IDirector(aSupervisor);
  70.  
  71.         itsAutopilotButton := nil;
  72.         itsBankCheckBox := nil;
  73.         itsAOACheckBox := nil;
  74.         itsDirFieldPane := nil;
  75.         itsStickPane := nil;
  76.  
  77.         { Start on automatic pilot. }
  78.         isManual := FALSE;
  79.  
  80.         kTakeControlStr := Concat('Take', kCarriageReturn, 'Control ', kCommandKeySymbol, 'T');
  81.         kReleaseControlStr := Concat('Release', kCarriageReturn, 'Control ', kCommandKeySymbol, 'R');
  82.         kBankStr := Concat('Bank ', kCommandKeySymbol, 'B');
  83.         kAOAStr := Concat('AOA ', kCommandKeySymbol, 'A');
  84.  
  85.     end; { IFSGameDirector }
  86.  
  87.  
  88. { Free }
  89. {}
  90. { Post: Our game director has been disposed of. }
  91.  
  92.     procedure CFSGameDirector.Free;
  93.  
  94.     begin { Free }
  95.         { Each of the panes is in the display hierarchy, }
  96.         { and will be disposed of in the inherited method. }
  97.  
  98.         itsAutopilotButton := nil;
  99.         itsBankCheckBox := nil;
  100.         itsAOACheckBox := nil;
  101.         itsDirFieldPane := nil;
  102.         itsStickPane := nil;
  103.  
  104.         inherited Free;
  105.     end; { Free }
  106.  
  107.  
  108. { BuildWindow }
  109. {}
  110. { Post: The window which the game director supervises has been built. }
  111.  
  112.     procedure CFSGameDirector.BuildWindow;
  113.  
  114.         var
  115.             theAircraftPane: CFSAircraftPane;
  116.             theWindow: CBitmapWindow;
  117.             theButton: CButton;
  118.             theCheckBox: CCheckBox;
  119.             theDirFieldPane: CFSDirFieldPane;
  120.             thePaneBorder: CPaneBorder;
  121.             theStickPane: CFSStickPane;
  122.  
  123.     begin { BuildWindow }
  124.         { We create a window which does its drawing in an offscreen bitmap. }
  125.         { Note that in this particular class, the window is always non-color. }
  126.         new(theWindow);
  127.         theWindow.IWindow(WINDGame, FALSE, gDesktop, SELF);
  128.         itsWindow := theWindow;
  129.  
  130.         { The window is initially hidden, set by the resource. }
  131.         { We don't use the decorator, because it CenterWindow puts the window at the }
  132.         { centre of the desktop, when what we want is to centre the game and help }
  133.         { windows on the primary screen. }
  134.         theWindow.Move((screenBits.bounds.right - screenBits.bounds.left - kFSGameWindh - kFSHelpWindh) div 2, (screenBits.bounds.bottom - screenBits.bounds.top - kFSGameWindv) div 2 + 20);
  135.  
  136.         { Direction field }
  137.  
  138.         new(theDirFieldPane);
  139.         theDirFieldPane.IFSDirFieldPane(itsWindow, SELF, 2 * kDirFieldHalfWidth, 2 * kDirFieldHalfHeight, kDirFieldPanePosh, kDirFieldPanePosv, sizFIXEDSTICKY, sizFIXEDSTICKY);
  140.         itsDirFieldPane := theDirFieldPane;
  141.  
  142.         new(thePaneBorder);
  143.         thePaneBorder.IPaneBorder(kBorderFrame);
  144.         itsDirFieldPane.SetBorder(thePaneBorder);
  145.  
  146.         { Stability checkboxes. }
  147.  
  148.         new(theCheckBox);
  149.         theCheckBox.INewCheckBox(kCheckBoxLenh, kCheckBoxesLenv, kBankCheckBoxPosh, kBankCheckBoxPosv, kBankStr, kVisible, itsWindow, SELF);
  150.         itsBankCheckBox := theCheckBox;
  151.         itsBankCheckBox.SetValue(BUTTON_ON); { This will update the direction field pane. }
  152.  
  153.         new(theCheckBox);
  154.         theCheckBox.INewCheckBox(kCheckBoxLenh, kCheckBoxesLenv, kAOACheckBoxPosh, kAOACheckBoxPosv, kAOAStr, kVisible, itsWindow, SELF);
  155.         itsAOACheckBox := theCheckBox;
  156.         itsAOACheckBox.SetValue(BUTTON_ON); { This will update the direction field pane. }
  157.  
  158.         { Stick }
  159.  
  160.         new(theStickPane);
  161.         theStickPane.IFSStickPane(itsWindow, SELF, 2 * kStickHalfWidth, 2 * kStickHalfHeight, kStickPanePosh, kStickPanePosv, sizFIXEDSTICKY, sizFIXEDSTICKY);
  162.         itsStickPane := theStickPane;
  163.         itsStickPane.SetWantsClicks(TRUE);
  164.  
  165.         new(thePaneBorder);
  166.         thePaneBorder.IPaneBorder(kBorderFrame);
  167.         itsStickPane.SetBorder(thePaneBorder);
  168.  
  169.         { Aircraft pane. }
  170.  
  171.         new(theAircraftPane);
  172.         theAircraftPane.IFSAircraftPane(itsWindow, SELF, kAircraftPaneLenh, kAircraftPaneLenv, kAircraftPanePosh, kAircraftPanePosv, sizFIXEDSTICKY, sizFIXEDSTICKY);
  173.         itsAircraftPane := theAircraftPane;
  174.  
  175.         new(thePaneBorder);
  176.         thePaneBorder.IPaneBorder(kBorderFrame);
  177.         itsAircraftPane.SetBorder(thePaneBorder);
  178.  
  179.         { Autopilot button. }
  180.  
  181.         new(theButton);
  182.         theButton.INewButton(kAutopilotButtonLenh, kAutopilotButtonLenv, kAutopilotButtonPosh, kAutopilotButtonPosv, kTakeControlStr, kVisible, 0, itsWindow, SELF);
  183.         theButton.SetClickCmd(cmdTakeControl);
  184.         itsAutopilotButton := theButton;
  185.  
  186.     end; { BuildWindow }
  187.  
  188.  
  189. { UpdateMenus }
  190. {}
  191. { Post: The Flight menu has been configured. }
  192.  
  193.     procedure CFSGameDirector.UpdateMenus;
  194.  
  195.     begin { UpdateMenus }
  196.         inherited UpdateMenus;
  197.  
  198.         if isManual then begin
  199.             gBartender.EnableCmd(cmdReleaseControl);
  200.         end { if }
  201.         else begin
  202.             gBartender.EnableCmd(cmdTakeControl);
  203.         end; { else }
  204.  
  205.     end; { UpdateMenus }
  206.  
  207.  
  208. { DoCommand }
  209. {}
  210. { Post: The game director has reacted to the command with the given id. }
  211.  
  212.     procedure CFSGameDirector.DoCommand (theCommand: longint);
  213.  
  214.         var
  215.             theMousePt: Point;
  216.  
  217.     begin { DoCommand }
  218.         if theCommand = cmdTakeControl then begin
  219.             isManual := TRUE;
  220.  
  221.             { Tell the stick pane to get the old mouse position }
  222.             { ready for control measurement. }
  223.             itsStickPane.InitOldMousePt;
  224.  
  225.             itsAutopilotButton.SetTitle(kReleaseControlStr);
  226.             itsAutopilotButton.SetClickCmd(cmdReleaseControl);
  227.         end { if }
  228.         else if theCommand = cmdReleaseControl then begin
  229.             isManual := FALSE;
  230.  
  231.             { Tell the stick pane to centre the stick. }
  232.             itsStickPane.CentreStick;
  233.  
  234.             itsAutopilotButton.SetTitle(kTakeControlStr);
  235.             itsAutopilotButton.SetClickCmd(cmdTakeControl);
  236.         end { else if }
  237.         else begin
  238.             inherited DoCommand(theCommand);
  239.         end; { else }
  240.     end; { DoCommand }
  241.  
  242.  
  243. { DoKeyDown }
  244. {}
  245. { Post: The game director has reacted to a key down event. }
  246.  
  247.     procedure CFSGameDirector.DoKeyDown (theChar: char; keyCode: Byte; macEvent: EventRecord);
  248.  
  249.     begin { DoKeyDown }
  250.         if (BAND(macEvent.modifiers, cmdKey) <> 0) then begin
  251.             case theChar of
  252.                 'a', 'A':  begin
  253.                     itsAOACheckBox.SimulateClick;
  254.                 end; { 'a', 'A' }
  255.                 'b', 'B':  begin
  256.                     itsBankCheckBox.SimulateClick;
  257.                 end; { 'b', 'B' }
  258.                 'r', 'R':  begin
  259.                     if isManual then begin
  260.                         itsAutopilotButton.SimulateClick;
  261.                     end; { if }
  262.                 end; { 'r', 'R' }
  263.                 't', 'T':  begin
  264.                     if not isManual then begin
  265.                         itsAutopilotButton.SimulateClick;
  266.                     end; { if }
  267.                 end; { 't', 'T' }
  268.                 otherwise begin
  269.                     inherited DoKeyDown(theChar, keyCode, macEvent);
  270.                 end; { otherwise }
  271.             end; { case }
  272.         end { if }
  273.         else begin
  274.             inherited DoKeyDown(theChar, keyCode, macEvent)
  275.         end; { else }
  276.     end; { DoKeyDown }
  277.  
  278.  
  279. { ProviderChanged }
  280. {}
  281. { Post: If one of the stability check boxes has changed value, then inform the direction field. }
  282.  
  283.     procedure CFSGameDirector.ProviderChanged (aProvider: CCollaborator; reason: Longint; info: univ Ptr);
  284.  
  285.         var
  286.             theCheckBox: CCheckBox;
  287.  
  288.     begin { ProviderChanged }
  289.         if member(aProvider, CCheckbox) then begin
  290.             theCheckBox := CCheckBox(aProvider);
  291.             if theCheckBox = itsBankCheckBox then begin
  292.                 itsDirFieldPane.SetBankStability(theCheckBox.IsChecked);
  293.             end { if }
  294.             else if theCheckBox = itsAOACheckBox then begin
  295.                 itsDirFieldPane.SetAOAStability(theCheckBox.IsChecked);
  296.             end; { else if }
  297.         end { if }
  298.         else begin
  299.             inherited ProviderChanged(aProvider, reason, info);
  300.         end; { else }
  301.     end; { ProviderChanged }
  302.  
  303.  
  304. { Dawdle }
  305. {}
  306. { Post: The stick position has been taken, the aircrafts motion in the }
  307. {        direction field has been updated, and used to update the aircraft. }
  308. {    Note: Put the minimum of stuff in here, this is the main animation loop. }
  309.  
  310.     procedure CFSGameDirector.Dawdle (var maxSleep: longint);
  311.  
  312.         var
  313.             changeBank, changeAOA: Real;
  314.             theBank, theAOA: Real;
  315.  
  316.     begin { Dawdle }
  317.         maxSleep := 0;
  318.         if isManual then begin
  319.             itsStickPane.GetControl(changeBank, changeAOA);
  320.             itsDirFieldPane.UpdatePosition(changeBank, changeAOA);
  321.         end { if }
  322.         else begin
  323.             itsDirFieldPane.SetCurrPosition(0, 0);
  324.         end;
  325.         itsDirFieldPane.GetCurrPosition(theBank, theAOA);
  326.         itsAircraftPane.UpdateAircraft(theBank, theAOA);
  327.     end; { Dawdle }
  328.  
  329. end. { CFSGameDirector }